import socket
from threading import Thread

def parse_seq(seq):
    """
    解析帧序列域SEQ。

    :param seq: 包含SEQ的字节串，SEQ是单个字节。
    :return: SEQ各部分的值。
    """
    if len(seq) != 1:
        raise ValueError("SEQ must be a single byte")

    # 将字节串转换为整数以便于位操作
    seq_int = int.from_bytes(seq, byteorder='big')

    # 解析各部分的值
    tpv = (seq_int >> 7) & 0b1
    fir = (seq_int >> 6) & 0b1
    fin = (seq_int >> 5) & 0b1
    con = (seq_int >> 4) & 0b1
    pseq_rseq = seq_int & 0b1111

    # 构建返回的字典
    seq_info = {
        "TpV": tpv,
        "FIR": fir,
        "FIN": fin,
        "CON": con,
        "PSEQ/RSEQ": pseq_rseq
    }

    return seq_info
def parse_control_field(control_byte):
    """
    解析控制域。

    :param control_byte: 控制域的字节。
    :return: 控制域各部分的值。
    """
    if len(control_byte) != 1:
        raise ValueError("Control field must be a single byte")

    # 将字节串转换为整数以便于位操作
    control_int = int.from_bytes(control_byte, byteorder='big')

    # 解析各部分的值
    dir_bit = (control_int >> 7) & 0b1
    prm_bit = (control_int >> 6) & 0b1
    fcb_bit = (control_int >> 5) & 0b1
    fcv_bit = (control_int >> 4) & 0b1
    function_code = control_int & 0b01111

    # 构建返回的字典
    control_info = {
        "DIR": dir_bit,
        "PRM": prm_bit,
        "FCB": fcb_bit,
        "FCV": fcv_bit,
        "Function Code": function_code
    }

    return control_info

def parse_user_data(user_data):
    """
    解析用户数据区，提取AFN, PN, DI及数据内容。

    :param user_data: 用户数据区的字节串。
    :return: 解析后的字典，包含AFN, PN, DI及数据内容。
    """
    frame_info = {}

    # 解析AFN（应用层功能码）
    if len(user_data) < 1:
        return "Invalid user data: insufficient length for AFN"
    # print(user_data)
    afn = user_data[0:1]
    frame_info["AFN"] = afn.hex()

    seq = user_data[1:2]
    frame_info["SEQ"] = seq.hex()
    frame_info["SEQINFO"] = parse_seq(seq)

    # 解析PN（信息点标识）
    if len(user_data) < 3:
        return "Invalid user data: insufficient length for PN"
    pn = user_data[2:4]
    frame_info["DA"] = pn.hex()

    # 解析DI（数据标识）
    if len(user_data) < 7:
        return "Invalid user data: insufficient length for DI"
    di = user_data[4:8]
    di_big_endian = int.from_bytes(di, byteorder='little')
    frame_info["DI"] = f"{di_big_endian:08X}"

    # 解析数据内容
    data_start = 8  # DI之后是数据内容的开始
    data_content = user_data[data_start:]
    frame_info["Data"] = data_content.hex()

    return frame_info



def parse_frame(raw_frame):
    """
    解析通信规约帧。

    :param raw_frame: 原始帧的字节串，包括起始字符、长度、控制域、地址域、链路用户数据和结束字符。
    :return: 解析后的帧信息字典。
    """
    # 帧结构定义
    frame_structure = {
        "start_char": 0x68,
        "length": 2,  # 字节长度
        "control_field": 1,  # 字节长度
        "address_field": 7,  # 字节长度
        "checksum": 1,  # 字节长度
        "end_char": 0x16,
    }

    # 检查起始字符
    if raw_frame[0] != frame_structure["start_char"]:
        return "Invalid frame: incorrect start character"

    # 解析用户数据区长度（小端字节序）
    length = int.from_bytes(raw_frame[1:3], byteorder='little')

    # 计算整个帧的长度
    total_length = length + 8  # 用户数据区长度 + 帧头（8字节）

    # 检查帧长度
    if len(raw_frame) != total_length:
        print("total:", total_length, "user:", length, "input:", len(raw_frame))
        return "Invalid frame: length mismatch"

    # 确保帧包含结束字符
    if raw_frame[-1] != frame_structure["end_char"]:
        return "Invalid frame: incorrect end character"

    # 解析控制域
    # print(raw_frame[7:].hex())
    control_field = raw_frame[6:7]
    control_field_info = parse_control_field(control_field)

    # 解析地址域
    address_field = raw_frame[7:7+7]

    # 解析用户数据区
    user_data_start = 14
    user_data_length = length - frame_structure["address_field"] - frame_structure["control_field"]   # 减去地址域、控制域和校验和的字节
    user_data = raw_frame[user_data_start:user_data_start + user_data_length]

    user_data_info = parse_user_data(user_data)

    # 解析校验和
    checksum = raw_frame[-2:]

    # 构建返回的帧信息字典
    frame_info = {
        "Start Character": frame_structure["start_char"],
        "Length": length,
        "Control Field": control_field.hex(),
        "Control Field Info": control_field_info,        
        "Address Field": address_field.hex(),
        "User Data": user_data.hex(),
        "User Data Info": user_data_info,
        "Checksum": checksum.hex(),
        "End Character": frame_structure["end_char"]
    }

    return frame_info
 